package com.sanben;

import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.core.toolkit.StringPool;
import com.baomidou.mybatisplus.generator.AutoGenerator;
import com.baomidou.mybatisplus.generator.InjectionConfig;
import com.baomidou.mybatisplus.generator.config.*;
import com.baomidou.mybatisplus.generator.config.po.TableInfo;
import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PropertiesLoaderUtils;

import java.io.IOException;
import java.util.*;

/**
 * @author cyh
 * @description: mybatis plus自动生成代码
 * @date: 2020/8/03 10:57
 */
@Data
@Slf4j
public class CodeGenerator {

	/**
	 * 代码生成的包名
	 */
	private String packageName = "com.sanben.demand";

	/**
	 * 需要去掉的表前缀
	 */
	private String[] tablePrefix = {""};
	/**
	 * 需要生成的表名(两者只能取其一)
	 */
	private String[] includeTables = {"comment_reply"};
	/**
	 * 需要排除的表名(两者只能取其一)
	 */
	private String[] excludeTables = {};
	/**
	 * 是否包含基础业务字段
	 */
	private Boolean hasSuperEntity = Boolean.TRUE;

	/**
	 * 基础业务字段
	 */
	private String[] superEntityColumns = {"created", "updated", "deleted"};
	/**
	 * 是否启用swagger
	 */
	private Boolean isSwagger2 = Boolean.TRUE;

	/**
	 * 开发者
	 */
	private String author="cyh";

	public void run() {
		//代码生成器
		AutoGenerator mpg = new AutoGenerator();

		//全局配置
		GlobalConfig gc = new GlobalConfig();
		String outputDir = getOutputDir();
		gc.setOutputDir(outputDir);
		gc.setIdType(IdType.AUTO);
		gc.setAuthor(author);
		gc.setFileOverride(true);
		gc.setOpen(false);
		gc.setActiveRecord(false);
		gc.setEnableCache(false);
		gc.setBaseResultMap(true);
		gc.setBaseColumnList(true);
		gc.setMapperName("%sMapper");
		gc.setXmlName("%sMapper");
		gc.setServiceName("I%sService");
		gc.setServiceImplName("%sServiceImpl");
		gc.setControllerName("%sController");
		gc.setSwagger2(isSwagger2);
		mpg.setGlobalConfig(gc);
		// 数据源配置
		DataSourceConfig dsc = new DataSourceConfig();
		dsc.setUrl("jdbc:mysql://121.196.124.190:3306/crowd_sourcing?useUnicode=true&characterEncoding=utf-8&serverTimezone=Asia/Shanghai");
		dsc.setDriverName("com.mysql.cj.jdbc.Driver");
		dsc.setUsername("root");
		dsc.setPassword("qwer145200");
		mpg.setDataSource(dsc);
		// 策略配置
		StrategyConfig strategy = new StrategyConfig();
		// strategy.setCapitalMode(true);// 全局大写命名
		// strategy.setDbColumnUnderline(true);//全局下划线命名
		strategy.setNaming(NamingStrategy.underline_to_camel);
		strategy.setColumnNaming(NamingStrategy.underline_to_camel);
		strategy.setTablePrefix(tablePrefix);
		if (includeTables.length > 0) {
			strategy.setInclude(includeTables);
		}
		if (excludeTables.length > 0) {
			strategy.setExclude(excludeTables);
		}
		if (hasSuperEntity) {
			strategy.setSuperEntityColumns(superEntityColumns);
		}
		// 自定义 controller 父类
		strategy.setEntityBuilderModel(false);
		strategy.setEntityLombokModel(true);
		strategy.setControllerMappingHyphenStyle(true);
		mpg.setStrategy(strategy);
		// 包配置
		PackageConfig pc = new PackageConfig();
		// 控制台扫描
		pc.setModuleName(null);
		pc.setParent(packageName);
		pc.setController("controller");
		pc.setEntity("entity");
		mpg.setPackageInfo(pc);
		mpg.setCfg(getInjectionConfig());
		TemplateConfig templateConfig = new TemplateConfig();
		templateConfig.setXml(null);
		mpg.setTemplate(templateConfig);
		mpg.execute();
	}

	private InjectionConfig getInjectionConfig() {
		// 自定义配置
		Map<String, Object> map = new HashMap<>(16);

		InjectionConfig cfg = new InjectionConfig() {
			@Override
			public void initMap() {
				this.setMap(map);
			}
		};
		List<FileOutConfig> focList = new LinkedList<>();
		focList.add(new FileOutConfig("/templates/entityDto.java.vm") {
			@Override
			public String outputFile(TableInfo tableInfo) {
				return getOutputDir() + "/" + packageName.replace(".", "/") + "/data/" + "dto" + "/" + tableInfo.getEntityName() + "Dto" + StringPool.DOT_JAVA;

			}
		});
		// 自定义配置会被优先输出
		focList.add(new FileOutConfig("/templates/mapper.xml.vm") {
			@Override
			public String outputFile(TableInfo tableInfo) {
				// 自定义输出文件名 ， 如果你 Entity 设置了前后缀、此处注意 xml 的名称会跟着发生变化！！
				return System.getProperty("user.dir") + "/src/main/resources/mapper/" +
						tableInfo.getEntityName() + "Mapper.xml";
			}
		});
		focList.add(new FileOutConfig("/templates/entityVo.java.vm") {
			@Override

			public String outputFile(TableInfo tableInfo) {
				// 自定义输出文件名 ， 如果你 Entity 设置了前后缀、此处注意 xml 的名称会跟着发生变化！！
				return getOutputDir() + "/" + packageName.replace(".", "/") + "/data/" + "vo" + "/" + tableInfo.getEntityName() + "Vo" + StringPool.DOT_JAVA;
			}
		});
		focList.add(new FileOutConfig("/templates/entityReq.java.vm") {
			@Override
			public String outputFile(TableInfo tableInfo) {
				// 自定义输出文件名 ， 如果你 Entity 设置了前后缀、此处注意 xml 的名称会跟着发生变化！！
				return getOutputDir() + "/" + packageName.replace(".", "/") + "/data/" + "req" + "/" + tableInfo.getEntityName() + "Req" + StringPool.DOT_JAVA;
			}
		});
		cfg.setFileOutConfigList(focList);
		return cfg;
	}

	/**
	 * 获取配置文件
	 *
	 * @return 配置Props
	 */
	private Properties getProperties() {
		// 读取配置文件
		Resource resource = new ClassPathResource("/templates/code.properties");
		Properties props = new Properties();
		try {
			props = PropertiesLoaderUtils.loadProperties(resource);
		} catch (IOException e) {
			e.printStackTrace();
		}
		return props;
	}

	/**
	 * 生成到项目中
	 *
	 * @return outputDir
	 */
	public String getOutputDir() {
		return System.getProperty("user.dir") + "/src/main/java";
	}

	public static void main(String[] args) {
		CodeGenerator bladeCodeGenerator = new CodeGenerator();
		bladeCodeGenerator.run();
	}
}
